package cn.com.easy.pay.alipay.app.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;

import cn.com.easy.dto.MessageDTO;
import cn.com.easy.exception.BusinessException;
import cn.com.easy.pay.alipay.union.config.AlipayUnionConfig;
import cn.com.easy.utils.ResponseOutputUtils;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;

/**
 * 支付宝 支付订单 签名基础控制器 <br/>
 * 
 * https://doc.open.alipay.com/docs/doc.htm?treeId=54&articleId=106370&docType=1
 * 
 * @author nibili 2017年4月6日
 * 
 */
public abstract class AlipayAppSignBaseController {

	private Logger logger = LoggerFactory.getLogger(AlipayAppSignBaseController.class);

	/**
	 * 业务参数
	 * 
	 * @return
	 * @author nibili 2017年4月6日
	 */
	public abstract AlipayTradeAppPayModel getAlipayTradeAppPayModel(HttpServletRequest httpServletRequest) throws BusinessException;

	/**
	 * 阿里配置参数
	 * 
	 * @return
	 * @author nibili 2017年4月1日
	 */
	public abstract AlipayUnionConfig getAlipayConfig(HttpServletRequest httpServletRequest) throws BusinessException;

	@RequestMapping("/sign.json")
	public void sign(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
		try {
			//
			AlipayUnionConfig alipayConfig = getAlipayConfig(httpServletRequest);
			//
			// AlipayOrderParam alipayOrderParam =
			// getAlipayOrderParam(httpServletRequest);
			// 实例化客户端
			AlipayClient alipayClient = new DefaultAlipayClient(AlipayUnionConfig.URL, alipayConfig.getApp_id(), alipayConfig.getRsa_private_key(), AlipayUnionConfig.FORMAT,
					AlipayUnionConfig.CHARSET, alipayConfig.getAlipay_public_key(), alipayConfig.getSigntype());
			// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
			AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
			// SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
			// AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
			// model.setBody(alipayOrderParam.getBody());
			// model.setSubject(alipayOrderParam.getSubject());
			// model.setOutTradeNo(alipayOrderParam.getOut_trade_no());
			// model.setTimeoutExpress(alipayOrderParam.getTimeout_express());
			// model.setTotalAmount(alipayOrderParam.getTotal_amount());
			// model.setProductCode(alipayOrderParam.getProduct_code());
			AlipayTradeAppPayModel model = this.getAlipayTradeAppPayModel(httpServletRequest);
			request.setBizModel(model);
			request.setNotifyUrl(alipayConfig.getNotify_url());
			// 这里和普通的接口调用不同，使用的是sdkExecute
			AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
			String body = response.getBody();// 就是orderString
												// 可以直接给客户端请求，无需再做处理。
			ResponseOutputUtils.renderJson(httpServletResponse, MessageDTO.newInstance("", true, body));
		} catch (Exception e) {
			ResponseOutputUtils.renderJson(httpServletResponse, MessageDTO.newInstance("", false, "订单签名异常，请稍后再试"));
			logger.error("", e);
		}
	}

	// /**
	// * 订单参数
	// *
	// * @author nibili 2017年4月6日
	// *
	// */
	// public static class AlipayOrderParam {
	// /** 商户订单号，商户网站订单系统中唯一订单号，必填 */
	// private String out_trade_no = "";
	// /** 订单名称，必填 */
	// private String subject = "";
	// /** 付款金额，必填 */
	// private String total_amount = "";
	// /** 商品描述，可空 */
	// private String body = "";
	// /**
	// * 超时时间 可空
	// * 该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下
	// * ，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
	// */
	// private String timeout_express = "";
	// /** 销售产品码 必填 */
	// private String product_code = "QUICK_WAP_PAY";
	//
	// /**
	// * get 商户订单号，商户网站订单系统中唯一订单号，必填
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getOut_trade_no() {
	// return out_trade_no;
	// }
	//
	// /**
	// * set 商户订单号，商户网站订单系统中唯一订单号，必填
	// *
	// * @param out_trade_no
	// * @author nibili 2017年4月7日
	// */
	// public void setOut_trade_no(String out_trade_no) {
	// this.out_trade_no = out_trade_no;
	// }
	//
	// /**
	// * get 订单名称，必填
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getSubject() {
	// return subject;
	// }
	//
	// /**
	// * set 订单名称，必填
	// *
	// * @param subject
	// * @author nibili 2017年4月7日
	// */
	// public void setSubject(String subject) {
	// this.subject = subject;
	// }
	//
	// /**
	// * get 付款金额，必填
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getTotal_amount() {
	// return total_amount;
	// }
	//
	// /**
	// * set 付款金额，必填
	// *
	// * @param total_amount
	// * @author nibili 2017年4月7日
	// */
	// public void setTotal_amount(String total_amount) {
	// this.total_amount = total_amount;
	// }
	//
	// /**
	// * get 商品描述，可空
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getBody() {
	// return body;
	// }
	//
	// /**
	// * set 商品描述，可空
	// *
	// * @param body
	// * @author nibili 2017年4月7日
	// */
	// public void setBody(String body) {
	// this.body = body;
	// }
	//
	// /**
	// * get 超时时间可空
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getTimeout_express() {
	// return timeout_express;
	// }
	//
	// /**
	// * set 超时时间可空
	// *
	// * @param timeout_express
	// * @author nibili 2017年4月7日
	// */
	// public void setTimeout_express(String timeout_express) {
	// this.timeout_express = timeout_express;
	// }
	//
	// /**
	// * get 销售产品码必填
	// *
	// * @return
	// * @author nibili 2017年4月7日
	// */
	// public String getProduct_code() {
	// return product_code;
	// }
	//
	// /**
	// * set 销售产品码必填
	// *
	// * @param product_code
	// * @author nibili 2017年4月7日
	// */
	// public void setProduct_code(String product_code) {
	// this.product_code = product_code;
	// }
	//
	// }

}
